package com.gitee.wsl.collections.map.iterator

import com.gitee.wsl.collections.iterator.api.MapIterator
import com.gitee.wsl.collections.iterator.api.MutableMapEntry
import com.gitee.wsl.collections.iterator.api.MutableMapIterator
import com.gitee.wsl.collections.iterator.api.ResettableIterator
import kotlin.jvm.Transient


/**
 * Adapts a Map entrySet to the MapIterator interface.
 *
 * @param <K> the type of the keys in the map
 * @param <V> the type of the values in the map
 * @since 4.0
</V></K> */
class EntrySetToMapIteratorAdapter<K, V>(
    /** The adapted Map entry Set.  */
    val entrySet: Set<Map.Entry<K, V>>,
) : MapIterator<K, V>, ResettableIterator<K> {
    /** The resettable iterator in use.  */
    @Transient
    var iterator: Iterator<Map.Entry<K, V>>? = null

    /** The currently positioned Map entry.  */
    @Transient
    var entry: Map.Entry<K, V>? = null

    /**
     * Create a new EntrySetToMapIteratorAdapter.
     * @param entrySet  the entrySet to adapt
     */
    init {
        reset()
    }

    /**
     * Gets the currently active entry.
     * @return Map.Entry&lt;K, V&gt;
     */
    //@Synchronized
    protected fun current(): Map.Entry<K, V> {
        checkNotNull(entry)
        return entry!!
    }

    /**
     * {@inheritDoc}
     */
    override fun getKey(): K {
        return current().key
    }

    /**
     * {@inheritDoc}
     */
    override fun getValue(): V {
        return current().value
    }

    /**
     * {@inheritDoc}
     */
    override fun hasNext(): Boolean {
        return iterator!!.hasNext()
    }

    /**
     * {@inheritDoc}
     */
    override fun next(): K {
        entry = iterator!!.next()
        return getKey()
    }

    /**
     * {@inheritDoc}
     */
    //@Synchronized
    override fun reset() {
        iterator = entrySet.iterator()
    }

}

class EntrySetToMapMutableIteratorAdapter<K, V>(
    /** The adapted Map entry Set.  */
    val entrySet: MutableSet<MutableMapEntry<K,V>>,
) : MutableMapIterator<K, V>, ResettableIterator<K> {
    /** The resettable iterator in use.  */
    @Transient
    lateinit var iterator: MutableIterator<MutableMapEntry<K, V>>

    /** The currently positioned Map entry.  */
    @Transient
    var entry: MutableMapEntry<K, V>? = null

    /**
     * Create a new EntrySetToMapIteratorAdapter.
     * @param entrySet  the entrySet to adapt
     */
    init {
        reset()
    }

    /**
     * Gets the currently active entry.
     * @return Map.Entry&lt;K, V&gt;
     */
    //@Synchronized
    protected fun current(): MutableMapEntry<K, V> {
        checkNotNull(entry)
        return entry!!
    }

    /**
     * {@inheritDoc}
     */
    override fun getKey(): K {
        return current().key
    }

    /**
     * {@inheritDoc}
     */
    override fun getValue(): V {
        return current().value
    }

    /**
     * {@inheritDoc}
     */
    override fun hasNext(): Boolean {
        return iterator.hasNext()
    }

    /**
     * {@inheritDoc}
     */
    override fun next(): K {
        entry = iterator.next()
        return getKey()
    }

    /**
     * {@inheritDoc}
     */
    public override fun remove() {
        iterator.remove()
        entry = null
    }

    /**
     * {@inheritDoc}
     */
    //@Synchronized
    override fun reset() {
        iterator = entrySet.iterator()
    }

    /**
     * {@inheritDoc}
     */
    override fun setValue(value: V): V {
        return current().setValue(value)
    }
}